package com.home.demo.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.home.demo.common.PageUtils;
import com.home.demo.common.Query;
import com.home.demo.dao.UserDao;
import com.home.demo.entity.RoleEntity;
import com.home.demo.entity.UserAndRoleEntity;
import com.home.demo.entity.UserEntity;
import com.home.demo.entity.dto.user.UserAndRoleSaveDTO;
import com.home.demo.entity.dto.user.UserListDTO;
import com.home.demo.entity.dto.user.UserUpdateDTO;
import com.home.demo.entity.vo.user.UserListVO;
import com.home.demo.entity.vo.user.UserLoginVO;
import com.home.demo.security.SecurityConfig;
import com.home.demo.service.RoleService;
import com.home.demo.service.UserAndRoleService;
import com.home.demo.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

@Service("userService")
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserDao, UserEntity> implements UserService {
    @Autowired
    private SecurityConfig securityConfig;

    @Autowired
    private UserAndRoleService userAndRoleService;

    @Autowired
    private RoleService roleService;


    /**
     * 查看所有用户分页
     * @param params
     * @return
     */
    @Override
    public PageUtils queryPage(Map<String, Object> params) {

        IPage<UserEntity> page = this.page(
                new Query<UserEntity>().getPage(params),
                new QueryWrapper<UserEntity>()
        );
        page.getRecords().stream().forEach(e->{
            List<String> roleIds = userAndRoleService.list(new QueryWrapper<UserAndRoleEntity>().eq("user_id", e.getId())).stream().map(UserAndRoleEntity::getRoleId).collect(Collectors.toList());
            if (roleIds!=null  && roleIds.size()>0) {
                RoleEntity byId = roleService.getById(roleIds.get(0));
                if(byId!=null) {
                    e.setRole( byId.getRole());
                }

            }
        });


        return new PageUtils(page);
    }

    /**
     * 注册账号
     * @param userAndRoleDTO
     */
    @Override
    @Transactional
    public boolean saveInfo(UserAndRoleSaveDTO userAndRoleDTO) {
        UserEntity user = new UserEntity();
        BeanUtils.copyProperties(userAndRoleDTO,user);

        if (user!=null&& StringUtils.hasText(user.getUsername())) {
            Long num = baseMapper.selectCount(new QueryWrapper<UserEntity>().eq("username", user.getUsername()));
            if (num==0L&& StringUtils.hasText(user.getPassword())) {
                String encode = securityConfig.passwordEncoder().encode(user.getPassword());
                user.setPassword(encode);
                baseMapper.insert(user);
                UserAndRoleEntity userAndRoleEntity = new UserAndRoleEntity();
                userAndRoleEntity.setRoleId(userAndRoleDTO.getRole());
                userAndRoleEntity.setUserId(user.getId());
                userAndRoleService.save(userAndRoleEntity);
                return true;
            }
        }

        return false;
    }

    /**
     * 修改用户信息 or 修改密码
     * @param user
     */

    @Override
    @Transactional
    public UserEntity updateByIdOrUpdatePassword(UserUpdateDTO user) {
        UserEntity userEntity = baseMapper.selectById(user.getId());
        List<UserAndRoleEntity> list = userAndRoleService.list(new QueryWrapper<UserAndRoleEntity>().eq("user_id", user.getId()).eq("role_id", user.getRole()));
        if (list.size()>0){
            UserAndRoleEntity userAndRoleEntity1 = list.get(0);
            userAndRoleEntity1.setRoleId(user.getRole());
            userAndRoleService.updateById(userAndRoleEntity1);

        }else {
            UserAndRoleEntity userAndRoleEntity = new UserAndRoleEntity();
            userAndRoleEntity.setUserId(user.getId());
            userAndRoleEntity.setRoleId(user.getRole());
            userAndRoleService.save(userAndRoleEntity);
        }

        String password = userEntity.getPassword();
        if (user!=null&&user.getOldPassword()!=null) {
            boolean matches = securityConfig.passwordEncoder().matches(user.getOldPassword(),userEntity.getPassword());
            if (matches){
                BeanUtils.copyProperties(user,userEntity);
                userEntity.setPassword(securityConfig.passwordEncoder().encode(userEntity.getPassword()));
                baseMapper.updateById(userEntity);
                return userEntity;
            }
            return null;
        }
        BeanUtils.copyProperties(user,userEntity);
        user.setPassword(password);
        baseMapper.updateById(userEntity);
        userAndRoleService.removeById(userEntity.getId());
        UserAndRoleEntity userAndRoleEntity = new UserAndRoleEntity();
        userAndRoleEntity.setUserId(userEntity.getId());
        userAndRoleEntity.setRoleId(user.getRole());
        userAndRoleService.save(userAndRoleEntity);


        return userEntity;
    }

    /**
     * 获取单个用户详情
     * @param username
     * @return
     */
    @Override
    public UserLoginVO selectUserInfo(String username) {
        UserLoginVO userLoginVO = baseMapper.selectUserInfo(username);
        List<UserLoginVO.MenuLoginVO> collect = userLoginVO.getMenuList().stream()
                .filter(e -> "0".equals(e.getParentId()))
                .map(e -> {
                    e.setChildren(userMenuTree(e, userLoginVO.getMenuList()));
                    return e;
                }).collect(Collectors.toList());
        userLoginVO.getMenuList().clear();
        userLoginVO.setMenuList(collect);

        System.out.println(userLoginVO);


        return userLoginVO;
    }

    private  List<UserLoginVO.MenuLoginVO> userMenuTree( UserLoginVO.MenuLoginVO parent,List<UserLoginVO.MenuLoginVO> all){
        return all.stream().filter(e->{
            return parent.getMenuId().equals(e.getParentId());
        }).map(e->{
            e.setChildren(userMenuTree(e,all));
            return e;
        }).collect(Collectors.toList());
    }



    @Override
    public IPage<UserListVO> getUserList(Map<String, Object> params) {
        Long page = Long.valueOf((String) params.get("page"));
        Long limit = Long.valueOf((String) params.get("limit"));
        UserListDTO userListDTO = (UserListDTO) params.get("userListDTO");
        IPage<UserListVO> iPage =  baseMapper.getUserList(new Page<>(page,limit),userListDTO);

        return iPage;
    }

    @Override
    public List<UserEntity> getCareList() {
        Set<String> userId = userAndRoleService.list().stream()
                .filter(e -> "3".equals(e.getRoleId()))
                .map(UserAndRoleEntity::getUserId)
                .collect(Collectors.toSet());
        List<UserEntity> list = new ArrayList<>();
        if (userId.size()>0){
            list = this.list(new QueryWrapper<UserEntity>().in("id",userId));
        }


        return list;
    }

}